package cqrtplm.aop;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hustcad.plm.pdm.modeling.model.dto.TyplmGeneralOperationDTO;
import com.hustcad.plm.pdm.mpmlink.service.TyplmMpmCommonService;
import cqrtplm.constant.RTErrorCodeEnum;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class ProcessRouteAop {
    @Resource
    private TyplmMpmCommonService typlmMpmCommonService;
    @Around("execution(* com.hustcad.plm.pdm.mpmlink.service.TyplmMpmOperationAdaptationService.batchCreateOperation(com.hustcad.plm.pdm.modeling.model.dto.TyplmGeneralOperationDTO))")
    @SneakyThrows
    public Object beforeCreateProcessRoute(ProceedingJoinPoint point) {
        Object[] args = point.getArgs();
        TyplmGeneralOperationDTO dto = (TyplmGeneralOperationDTO)args[0];
        JSONObject parentObj = dto.getParentObj();
        String sotype = parentObj.getString("sotype");
        if(!"processSequence".equals(sotype) && !"processStage".equals(sotype)){
            return point.proceed();
        }
        List<JSONObject> currentObj = dto.getCurrentObj();
        List<JSONObject> processObj = this.typlmMpmCommonService.querySubObjectList(buildGeneralOperationDTO(parentObj.getString("oid"),parentObj.getString("typeotype")));
        if(CollUtil.isEmpty(processObj)){
            return point.proceed();
        }
        // 提取所有旧的 name 和 gxid 到 Map 中，便于快速查找
        Map<String, String> oldNameToIdMap = new HashMap<>();
        Map<String, String> oldIdToNameMap = new HashMap<>();

        for (JSONObject oldProcessObj : processObj) {
            String oldName = oldProcessObj.getString("name");
            String oldProcessId = extractValueFromIbaList(oldProcessObj.getJSONArray("ibaList"), "gxh");

            oldNameToIdMap.put(oldName, oldProcessId);
            oldIdToNameMap.put(oldProcessId, oldName);
        }

        // 遍历新工序，检查是否重复
        for (JSONObject newProcessObj : currentObj) {
            String newName = newProcessObj.getString("name");
            String newProcessId = extractValueFromIbaList(newProcessObj.getJSONArray("ibaList"), "gxh");

            if (oldNameToIdMap.containsKey(newName) || oldIdToNameMap.containsKey(newProcessId)) {
                if ("processStage".equals(parentObj.getString("sotype"))) {
                    throw RTErrorCodeEnum.WORK_FLOW_EXECUTE_EXCEPTION.getException(
                            "工序重复，不可创建，工序名称:" + newName + "工序号:" + newProcessId);
                } else {
                    throw RTErrorCodeEnum.WORK_FLOW_EXECUTE_EXCEPTION.getException(
                            "工步重复，不可创建，工步名称:" + newName + "工步号:" + newProcessId);
                }
            }
        }

        return point.proceed();
    }

    private String extractValueFromIbaList(JSONArray ibaList, String targetKey) {
        if(CollUtil.isEmpty(ibaList)){
            return null;
        }
        for (int i = 0; i < ibaList.size(); i++) {
            JSONObject ibaItem = ibaList.getJSONObject(i);
            if (targetKey.equals(ibaItem.getString("key"))) {
                return ibaItem.getString("value");
            }
        }
        return null;
    }

    public TyplmGeneralOperationDTO buildGeneralOperationDTO(String oid,String type) {
        JSONObject currentObj = new JSONObject();
        TyplmGeneralOperationDTO generalOperationDTO = new TyplmGeneralOperationDTO();
        currentObj.put("oid",oid);
        currentObj.put("otype",type);
        generalOperationDTO.setCurrentObj(ListUtil.toList(currentObj));
        generalOperationDTO.getParam().put("asyn", true);
        return generalOperationDTO;
    }
}
